package user;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.ArrayDataModel;
import javax.faces.model.DataModel;

import utils.MeasureunitDAORemote;
import utils.ResourceDAORemote;
import utils.ResponseDAORemote;
import utils.ResticketDAORemote;
import utils.TicketDAORemote;
import utils.UserDAORemote;
import beans.UserPageBean;
import dtos.MeasureunitDTO;
import dtos.ResourceDTO;
import dtos.ResticketDTO;
import dtos.ResticketHistoryDTO;
import dtos.UserDTO;

@ManagedBean
@SessionScoped
public class RequestResourceBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1424754153003793658L;
	private int resourceId;
	private int quantity;
	private String description;
	private int quantityType;
	private String errorMessage;
	private String confirmMessage;
	private ResourceDTO[] resources;
	private MeasureunitDTO[] umdtos;
	private List<MeasureunitDTO> listUMDTO;
	private List<ResourceDTO> listResourceDTO;
	private List<ResticketDTO> listResticketDTO;
	private List<ResticketHistoryDTO> listResticketHistoryDTO;
	private UserDTO currentUser;
	private ResticketHistoryDTO[] ticketsArray;
	private DataModel<ResticketHistoryDTO> tickets;
	private boolean emptyList;
	private boolean allowSendRequest;

	@EJB
	UserDAORemote udr;
	@EJB
	ResourceDAORemote rdr;
	@EJB
	TicketDAORemote tdr;
	@EJB
	ResticketDAORemote rtdr;
	@EJB
	MeasureunitDAORemote umdr;
	@EJB
	ResponseDAORemote redr;
	@ManagedProperty("#{userPageBean}")
	UserPageBean upb;

	ResourceBundle bundle = ResourceBundle.getBundle(
			"languageSettings.language", FacesContext.getCurrentInstance()
					.getViewRoot().getLocale());

	public RequestResourceBean() {

	}

	/**
	 *          Initializes the necessary lists for the combo boxes, to let the
	 *          user to select the resources and the measurement units
	 */
	@PostConstruct
	public void initialize() {

		// currentUser = udr.getUser(1);
		 currentUser = (UserDTO)
		 FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("loggedUser");
		// this.setAllowSendRequest(false);
		refreshListResourceDTO();
		// refreshListResticketDTO();
		refreshListUMDTO();
		setUmdtos(listUMDTO.toArray(new MeasureunitDTO[listUMDTO.size()]));
		setResources(listResourceDTO.toArray(new ResourceDTO[listResourceDTO
				.size()]));
		// refreshTicketsDataModel(false);
	}

	public UserDTO getCurrentUSer() {
		currentUser = (UserDTO) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("loggedUser");
		System.out.println("GGGGEEETTTT CCCUUURRREEENNNTTT UUUSSSEERRRR  IIIDDD:::::" +currentUser.getId()+ currentUser.getName());

		return currentUser;
	}

	/**
	 * @return the allowSendRequest
	 */
	public boolean isAllowSendRequest() {
		return allowSendRequest;
	}

	/**
	 * @return the allowSendRequest
	 */
	public boolean getAllowSendRequest() {
		return allowSendRequest;
	}

	/**
	 * @param allowSendRequest
	 *            the allowSendRequest to set
	 */
	public void setAllowSendRequest(boolean allowSendRequest) {
		this.allowSendRequest = allowSendRequest;
	}

	/**
	 * @return the emptyList
	 */
	public boolean isEmptyList() {
		if (this.getListResticketHistoryDTO().isEmpty()) {
			return false;
		} else {
			return true;
		}

	}

	/**
	 * @return the emptyList
	 */
	public boolean getEmptyList() {
		if (this.getListResticketHistoryDTO().isEmpty()) {
			return false;
		} else {
			return true;
		}

	}

	/**
	 * @param emptyList
	 *            the emptyList to set
	 */
	public void setEmptyList(boolean emptyList) {
		this.emptyList = emptyList;
	}

	/**
	 * Generates the list with all the resources
	 */
	public void refreshListResourceDTO() {
		listResourceDTO = rdr.getAllResources();
	}

	/**
	 * Generates the list with the tickets from the last
	 *         month
	 */
	public void refreshListResticketDTO() {
		listResticketDTO = rtdr.getResticketsByUserIdCurrentMonth(this
				.getCurrentUSer());
	}

	/**
	 * Generates the list with all the Measurement units
	 */
	public void refreshListUMDTO() {
		listUMDTO = umdr.getAllMeasureunits();
	}

	/**
	 * Generates the Data Model to display the tickets
	 */
	public void refreshTicketsDataModel(boolean fromSend) {
		refreshListResticketHistoryDTO(fromSend);
		convertTickets();
		tickets = new ArrayDataModel<>(ticketsArray);
	}

	/**
	 * Generates the list with the tickets containing all
	 *         the informations to display the tickets
	 */
	private void refreshListResticketHistoryDTO(boolean fromSend) {
		if (!fromSend) {
			this.setConfirmMessage(null);
		}
		List<ResticketHistoryDTO> tempList = new ArrayList<>();
		for (ResticketDTO r : listResticketDTO) {
			ResticketHistoryDTO tempTicket = new ResticketHistoryDTO();
			tempTicket.setTicketId(r.getId());
			tempTicket.setQuantity(r.getQuantity());
			tempTicket.setResourceName(rdr.getResource(r.getIdResource())
					.getName());
			if (r.getIdResponse() != 0) {
				tempTicket.setResponder(udr.getUser(
						redr.getResponse(r.getIdResponse()).getIdUser())
						.getName());
				tempTicket.setResponseDescription(redr.getResponse(
						r.getIdResponse()).getDescription());
				tempTicket.setResponseDate(redr.getResponse(r.getIdResponse())
						.getDate());
			}
			tempTicket.setStatus(r.getStatus());
			tempTicket.setTicketDescription(r.getDescription());
			tempTicket.setMeasureunit(umdr.getMeasureunit(r.getItMeasureunit())
					.getName());
			tempTicket.setDate(r.getDate());
			tempList.add(tempTicket);

		}
		this.setListResticketHistoryDTO(tempList);
	}

	/**
	 * Converts the list of tickets into an array of
	 *         tickets to be displayed
	 */
	public void convertTickets() {
		ticketsArray = listResticketHistoryDTO
				.toArray(new ResticketHistoryDTO[listResticketHistoryDTO.size()]);
	}

	public List<ResticketHistoryDTO> getListResticketHistoryDTO() {
		return listResticketHistoryDTO;
	}

	public void setListResticketHistoryDTO(
			List<ResticketHistoryDTO> listResticketHistoryDTO) {
		this.listResticketHistoryDTO = listResticketHistoryDTO;
	}

	public ResticketHistoryDTO[] getTicketsArray() {
		return ticketsArray;
	}

	public void setTicketsArray(ResticketHistoryDTO[] ticketsArray) {
		this.ticketsArray = ticketsArray;
	}

	public DataModel<ResticketHistoryDTO> getTickets() {
		return tickets;
	}

	public void setTickets(DataModel<ResticketHistoryDTO> tickets) {
		this.tickets = tickets;
	}

	public List<ResticketDTO> getListResticketDTO() {
		return listResticketDTO;
	}

	public void setListResticketDTO(List<ResticketDTO> listResticketDTO) {
		this.listResticketDTO = listResticketDTO;
	}

	public ResourceDTO[] getResources() {
		return resources;
	}

	public void setResources(ResourceDTO[] resourc) {

		this.resources = resourc;
	}

	public MeasureunitDTO[] getUmdtos() {
		return umdtos;
	}

	public void setUmdtos(MeasureunitDTO[] umdtos) {
		this.umdtos = umdtos;
	}

	public List<MeasureunitDTO> getListUMDTO() {
		return listUMDTO;
	}

	public void setListUMDTO(List<MeasureunitDTO> listUMDTO) {
		this.listUMDTO = listUMDTO;
	}

	public List<ResourceDTO> getListResourceDTO() {
		return listResourceDTO;
	}

	public void setListResourceDTO(List<ResourceDTO> listResourceDTO) {
		this.listResourceDTO = listResourceDTO;
	}

	public UserDTO getCurrentUser() {
		return currentUser;
	}

	public void setCurrentUser(UserDTO currentUser) {
		this.currentUser = currentUser;
	}

	public int getQuantityType() {
		return quantityType;
	}

	public void setQuantityType(int quantityType) {
		this.quantityType = quantityType;
	}

	public int getResourceId() {
		return resourceId;
	}

	public void setResourceId(int resourceId) {
		this.resourceId = resourceId;
	}

	public Integer getQuantity() {
		return quantity;
	}

	public void setQuantity(Integer quantity) {
		this.quantity = quantity;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	public void resourceChangeListener(ValueChangeEvent event) {
		this.setResourceId(Integer.parseInt((String) event.getNewValue()));
	}

	public void quantityTypeChangeListener(ValueChangeEvent event) {
		this.setQuantityType(Integer.valueOf((String) event.getNewValue()));
	}

	public String goToHistory() {
		return "requestHistory.xhtml";
	}

	/**
	 * @return the confirmMessage
	 */
	public String getConfirmMessage() {
		return confirmMessage;
	}

	/**
	 * @param confirmMessage
	 *            the confirmMessage to set
	 */
	public void setConfirmMessage(String confirmMessage) {
		this.confirmMessage = confirmMessage;
	}

	/**
	 * Sets the confirmation message to null
	 * 
	 */
	public String setConfirmNull() {
		this.setConfirmMessage(null);
		return "";
	}

	public void confMessage() {
		this.setConfirmMessage(bundle
				.getString("BU_requestResources_confirmMessage"));

	}

	public void quantityValueChanged(ValueChangeEvent event) {
		this.setAllowSendRequest(true);
		this.setConfirmMessage(null);
	}

	/**
	 * @return the upb
	 */
	public UserPageBean getUpb() {
		return upb;
	}

	/**
	 * @param upb
	 *            the upb to set
	 */
	public void setUpb(UserPageBean upb) {
		this.upb = upb;
	}

	/**
	 * @param event
	 *            Creates a ResticketDTO and sends to the EJB to send
	 *            notification, and to store the ticket in the database
	 */

	public void sendRequest(ActionEvent event) {
		currentUser = this.getCurrentUSer();

		this.setAllowSendRequest(false);
		this.setConfirmMessage(null);
		if (this.getListResourceDTO().size() != 0) {
			if (this.getListUMDTO().size() != 0) {
				ResticketDTO resticketDTO = new ResticketDTO();
				MeasureunitDTO measurementUnit = null;
				ResourceDTO resourceDTO = new ResourceDTO();

				for (MeasureunitDTO mu : listUMDTO) {
					if (mu.getId() == this.quantityType) {
						measurementUnit = mu;
					}
				}
				for (ResourceDTO re : listResourceDTO) {
					if (re.getId() == this.resourceId) {
						resourceDTO = re;
					}
				}

				Date date = new Date();
				resticketDTO.setItMeasureunit(measurementUnit.getId());
				resticketDTO.setDescription(description);
				resticketDTO.setDate(date);
				resticketDTO.setQuantity(quantity);
				resticketDTO.setIdResource(resourceDTO.getId());
				resticketDTO.setIdUser(currentUser.getId());
				resticketDTO.setStatus("Pending");
				setDescription(null);
				setQuantity(0);
				rtdr.insertResticket(resticketDTO);
				this.confMessage();
				refreshListResticketDTO();
				refreshTicketsDataModel(true);
			}
		}
	}

	public void goToHistory(ActionEvent event) {
		currentUser = this.getCurrentUSer();
		this.setAllowSendRequest(false);
		this.setQuantity(0);
		this.setConfirmMessage(null);
		this.setDescription(null);

		this.refreshListResticketDTO();
		refreshListResticketHistoryDTO(false);
		this.refreshTicketsDataModel(false);
		upb = (UserPageBean) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("userPageBean");
		upb.setPage("requestHistory");
		// System.out.println(upb);
	}

}
